﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Asion.Dapper
{
    /// <summary>
    /// crud repositroy
    /// </summary>
    public interface ICrudRepository<TEntity> : IRepository where TEntity : IEntity
    {

        int Insert(TEntity model, List<string> excludes = null);

        /// <summary>
        /// 批量插入
        /// <para>默认插入500条会延迟100毫秒，如果超过5000条则每次延迟500毫秒</para>
        /// <para>批量插入code暂时无法生产</para>
        /// </summary>
        /// <param name="models">插入实体</param>
        /// <param name="singleBatchCount">单次插入数量，默认500</param>
        /// <param name="delayMaxCount">延迟超过最大数量</param>
        /// <param name="delayDefaultSleepMillSeconds">默认延迟毫秒100</param>
        /// <param name="delayOverCountSleepMillSeconds">超过延迟数量则使用这个延迟超过睡眠毫秒</param>
        /// <returns></returns>
        int BatchInsert(List<TEntity> models, List<string> excludeColumns = null, int singleBatchCount = DapperConfiguration.batch_insert_count, int delayMaxCount = 5000, int delayDefaultSleepMillSeconds = 100, int delayOverCountSleepMillSeconds = 500);

        bool Delete(IWhere where);

        bool DeleteList(IWhere where);


        bool Update(TEntity model, IUpdateWhere where, List<string> excludes = null);

        int BatchUpdate(List<TEntity> models, string[] updateColmuns, string updateColmunsWhere, IWhere where, int singleBatchCount = DapperConfiguration.batch_update_count, int delayMaxCount = 5000, int delayDefaultSleepMillSeconds = 100, int delayOverCountSleepMillSeconds = 500);


        int Update(IUpdateColumn model, IWhere where);


        public SaveReponse Save(TEntity entity, IUpdateWhere where, SaveExcludeRequest excludeRequest);


        /// <summary>
        /// 批量保存
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="where"></param>
        /// <param name="excludeRequest"></param>
        /// <returns></returns>
        public BatchSaveReponse BatchSave(BatchSaveRequest<TEntity> request);
        /// <summary>
        /// 增加数量
        /// <para>example sql:update table set a+=1 where 1=1</para>
        /// </summary>
        /// <param name="column"></param>
        /// <param name="value"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        int IncreaseCount(string column, int value, IWhere where);

        /// <summary>
        /// 减少数量
        /// <para>example sql:update table set a-=1 where 1=1</para>
        /// </summary>
        /// <param name="column"></param>
        /// <param name="value"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        int DecreaseCount(string column, int value, IWhere where);

        [Obsolete("不建议使用，建议使用加入 column")]
        TEntity Get(IWhere where, IOrderBy order = null);


        TEntity Get(ISelectColumn column, IWhere where, IOrderBy order = null);

        IEnumerable<TEntity> GetList(IWhere where, IOrderBy order = null, IGroupColumn group = null);


        IEnumerable<TEntity> GetList(ISelectColumn column, IWhere where, IOrderBy order = null, IGroupColumn group = null);

        /// <summary>
        /// 获取top前几数据
        /// </summary>
        /// <param name="topCount"></param>
        /// <param name="column"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        IEnumerable<TEntity> GetTopList(int topCount, ISelectColumn column, IWhere where, IOrderBy order = null, IGroupColumn group = null);

        PageReponse<TEntity> GetPageList(ISelectColumn column, IWhere where, int pageNumber = 1, int rowsPerPage = DapperConfiguration.default_rows_page, IOrderBy order = null);

        int RecordCount(IWhere where);

        bool Exist(IWhere where);

        /// <summary>
        /// 连接查询
        /// </summary>
        /// <typeparam name="TFirst"></typeparam>
        /// <typeparam name="TSecond"></typeparam>
        /// <typeparam name="TReturn"></typeparam>
        /// <param name="sql"></param>
        /// <param name="map"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        IEnumerable<TReturn> Query<TFirst, TSecond, TReturn>(string sql, object param, Func<TFirst, TSecond, TReturn> map);



        /// <summary>
        /// 多个sql查询
        /// </summary>
        /// <typeparam name="TFirst"></typeparam>
        /// <typeparam name="TSecond"></typeparam>
        /// <typeparam name="TReturn"></typeparam>
        /// <param name="sql"></param>
        /// <param name="map"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Tuple<TReturn1, TReturn2> QueryMult<TReturn1, TReturn2>(string[] sqls, object param);


        /// <summary>
        /// 多个sql查询
        /// </summary>
        /// <typeparam name="TFirst"></typeparam>
        /// <typeparam name="TSecond"></typeparam>
        /// <typeparam name="TReturn"></typeparam>
        /// <param name="sql"></param>
        /// <param name="map"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        Tuple<TReturn1, TReturn2, TReturn3> QueryMult<TReturn1, TReturn2, TReturn3>(string[] sqls, object param);
    }
}
